﻿#region Copyright (c) 2013-08, Olaf Kober <amarok.projects@gmail.com>
//================================================================================
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.
//================================================================================
#endregion

using System;
using System.Runtime.InteropServices;


namespace Amarok.Presentation.Native
{
	/// <summary>
	/// This class contains platform invokes to window-related functions.
	/// </summary>
	internal static class UnsafeNativeWindow
	{
		// constants
		private const String LIBRARY = "user32.dll";


		/// <summary>
		/// Retrieves information about the specified window. The function also retrieves the value at a 
		/// specified offset into the extra window memory. 
		/// </summary>
		/// 
		/// <param name="hWnd">
		/// A handle to the window and, indirectly, the class to which the window belongs.</param>
		/// <param name="nIndex">
		/// The zero-based offset to the value to be retrieved. Valid values are in the range zero through the 
		/// number of bytes of extra window memory, minus four; for example, if you specified 12 or more bytes of 
		/// extra memory, a value of 8 would be an index to the third 32-bit integer.</param>
		/// 
		/// <returns>
		/// If the function succeeds, the return value is the requested value. If the function fails, the return 
		/// value is zero. To get extended error information, call GetLastError. If SetWindowLong or SetWindowLongPtr 
		/// has not been called previously, GetWindowLongPtr returns zero for values in the extra window or 
		/// class memory.
		/// </returns>
		[DllImport(LIBRARY, SetLastError = true, CharSet = CharSet.Unicode)]
		public static extern Int32 GetWindowLong(HandleRef hWnd, Int32 nIndex);

		/// <summary>
		/// Retrieves information about the specified window. The function also retrieves the value at a 
		/// specified offset into the extra window memory. 
		/// </summary>
		/// 
		/// <param name="hWnd">
		/// A handle to the window and, indirectly, the class to which the window belongs.</param>
		/// <param name="nIndex">
		/// The zero-based offset to the value to be retrieved. Valid values are in the range zero through the 
		/// number of bytes of extra window memory, minus four; for example, if you specified 12 or more bytes of 
		/// extra memory, a value of 8 would be an index to the third 32-bit integer.</param>
		/// 
		/// <returns>
		/// If the function succeeds, the return value is the requested value. If the function fails, the return 
		/// value is zero. To get extended error information, call GetLastError. If SetWindowLong or SetWindowLongPtr 
		/// has not been called previously, GetWindowLongPtr returns zero for values in the extra window or 
		/// class memory.
		/// </returns>
		[DllImport(LIBRARY, SetLastError = true, CharSet = CharSet.Unicode)]
		public static extern IntPtr GetWindowLongPtr(HandleRef hWnd, Int32 nIndex);


		/// <summary>
		/// Changes an attribute of the specified window. The function also sets a value at the specified offset in 
		/// the extra window memory. 
		/// </summary>
		/// 
		/// <param name="hwnd">
		/// A handle to the window and, indirectly, the class to which the window belongs.</param>
		/// <param name="index">
		/// The zero-based offset to the value to be set. Valid values are in the range zero through the number 
		/// of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of 
		/// the following values.</param>
		/// <param name="value">
		/// The replacement value.</param>
		/// 
		/// <returns>
		/// If the function succeeds, the return value is the previous value of the specified 32-bit integer. If 
		/// the function fails, the return value is zero. To get extended error information, call GetLastError. If 
		/// the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value 
		/// is zero, but the function does not clear the last error information. This makes it difficult to determine 
		/// success or failure. To deal with this, you should clear the last error information by calling SetLastError 
		/// with 0 before calling SetWindowLong. Then, function failure will be indicated by a return value of zero 
		/// and a GetLastError result that is nonzero.
		/// </returns>
		[DllImport(LIBRARY, SetLastError = true, CharSet = CharSet.Unicode)]
		public extern static Int32 SetWindowLong(HandleRef hwnd, Int32 index, Int32 value);

		/// <summary>
		/// Changes an attribute of the specified window. The function also sets a value at the specified offset in 
		/// the extra window memory. 
		/// </summary>
		/// 
		/// <param name="hwnd">
		/// A handle to the window and, indirectly, the class to which the window belongs.</param>
		/// <param name="index">
		/// The zero-based offset to the value to be set. Valid values are in the range zero through the number 
		/// of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of 
		/// the following values.</param>
		/// <param name="value">
		/// The replacement value.</param>
		/// 
		/// <returns>
		/// If the function succeeds, the return value is the previous value of the specified 32-bit integer. If 
		/// the function fails, the return value is zero. To get extended error information, call GetLastError. If 
		/// the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value 
		/// is zero, but the function does not clear the last error information. This makes it difficult to determine 
		/// success or failure. To deal with this, you should clear the last error information by calling SetLastError 
		/// with 0 before calling SetWindowLong. Then, function failure will be indicated by a return value of zero 
		/// and a GetLastError result that is nonzero.
		/// </returns>
		[DllImport(LIBRARY, SetLastError = true, CharSet = CharSet.Unicode)]
		public extern static IntPtr SetWindowLongPtr(HandleRef hwnd, Int32 index, IntPtr value);

	}
}
